package com.mbc.common.manager;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRResultSetDataSource;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;

import com.mbc.common.CommonSingleton;
import com.mbc.common.dao.CommonDAOFactory;
import com.mbc.common.dao.CurrencyRateDAO;
import com.mbc.common.dao.CurrencyRateDetailDAO;
import com.mbc.common.dao.DBManager;
import com.mbc.common.dao.DBManagerFactory;
import com.mbc.common.dao.IAIMSCurrencyRateDAO;
import com.mbc.common.dao.IAIMSCurrencyRateDetailDAO;
import com.mbc.common.dao.LogDAO;
import com.mbc.common.data.CurrencyRateDataList;
import com.mbc.common.entities.Currency;
import com.mbc.common.entities.CurrencyRate;
import com.mbc.common.entities.CurrencyRateDetail;
import com.mbc.common.entities.CurrencyRateRpt;
import com.mbc.common.entities.Log;
import com.mbc.common.exception.DataDuplicationException;
import com.mbc.common.exception.ForeignConflictException;
import com.mbc.common.utils.KeyGenerator;

public class CurrencyRateMgr extends AbstractMgr {

	CurrencyRateDAO currencyRateDAO;
	LogDAO logDAO;
	
	public CurrencyRateMgr()
	{}
	
	public CurrencyRateMgr(String sessionId)
	{
		this.sessionId = sessionId;
	}
	
	public void createCurrencyRate(CurrencyRate currencyRate)throws Exception{
		DBManager l_DBManager  = DBManagerFactory.getDBManager(DBManager.LINKED_IAIMS);
		openConnection();
		try {
			l_DBManager.beginTransaction();
			dbManager.beginTransaction();
			
			currencyRateDAO = CommonDAOFactory.getCurrencyRateDAO(dbManager.getConnection());
			CurrencyRateDetailDAO l_CurrencyRateDetailDAO = CommonDAOFactory.getCurrencyRateDetailDAO(dbManager.getConnection());
			logDAO = CommonDAOFactory.getLogDAO(getConnection());
			
			if(currencyRateDAO.findByCode(currencyRate.getCurrencyRateCode(),currencyRate.getBranchId()) != null)
				throw new DataDuplicationException("Currency Rate with this ID is already existed.");
			currencyRate.setCurrencyRateId(KeyGenerator.generateKey(dbManager.getConnection()));
			currencyRateDAO.create(currencyRate);

			Log l_logentity = new Log();
			l_logentity.setTablename("CurrencyRate");
			l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
			l_logentity.setKey(currencyRate.getCurrencyRateId());
			l_logentity.setUserid(currencyRate.getUserid());
			l_logentity.setLogstatus(Log.__SAVE_DATA);
			logDAO.getData(l_logentity);
			
			currencyRate.getCurrencyRateDetail().setCurrencyRateId(currencyRate.getCurrencyRateId());
			currencyRate.getCurrencyRateDetail().setCurrencyRateDetailId(KeyGenerator.generateKey(dbManager.getConnection()));
			l_CurrencyRateDetailDAO.create(currencyRate.getCurrencyRateDetail());

			l_logentity.setTablename("CurrencyRateDetail");
			l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
			l_logentity.setKey(currencyRate.getCurrencyRateDetail().getCurrencyRateDetailId());
			l_logentity.setLogstatus(Log.__SAVE_DATA);
			logDAO.getData(l_logentity);
			
			IAIMSCurrencyRateDAO l_currencyRateDAO = CommonDAOFactory.getIAIMSCurrencyRateDAO(l_DBManager.getConnection());
			IAIMSCurrencyRateDetailDAO l_detailDAO = CommonDAOFactory.getIAIMSCurrencyRateDetailDAO(l_DBManager.getConnection());
			
			CurrencyRate l_existingCR = l_currencyRateDAO.findByCode(currencyRate.getCurrencyRateCode(),currencyRate.getBranchId());
			if(l_existingCR == null){
				currencyRate.setCurrencyRateId(KeyGenerator.generateKey(l_DBManager.getConnection()));
				if(currencyRate.getRoper().equals("D"))
					currencyRate.setRoper("0");
				else if(currencyRate.getRoper().equals("M"))
					currencyRate.setRoper("1");
				l_currencyRateDAO.create(currencyRate);
				currencyRate.getCurrencyRateDetail().setCurrencyRateId(currencyRate.getCurrencyRateId());
			}else{
				currencyRate.getCurrencyRateDetail().setCurrencyRateId(l_existingCR.getCurrencyRateId());
			}
			
			currencyRate.getCurrencyRateDetail().setCurrencyRateDetailId(KeyGenerator.generateKey(l_DBManager.getConnection()));
			l_detailDAO.create(currencyRate.getCurrencyRateDetail());
			
			dbManager.commitTransaction();
			l_DBManager.commitTransaction();
		} catch (SQLException e) {
			l_DBManager.rollBackTransaction();
			dbManager.rollBackTransaction();
			if(DataDuplicationException.UNIQUE_KEY_ERROR_CODE == e.getErrorCode())
				throw new DataDuplicationException(e.getMessage());
			else
				throw e;
		}
		finally{
			l_DBManager.closeConnection();
			dbManager.closeConnection();
		}
	}
	
	public void updateCurrencyRate(CurrencyRate currencyRate)throws Exception{
		DBManager l_DBManager = DBManagerFactory.getDBManager(DBManager.LINKED_IAIMS);
		openConnection();
		try {
			dbManager.beginTransaction();
			l_DBManager.beginTransaction();
			
			currencyRateDAO = CommonDAOFactory.getCurrencyRateDAO(dbManager.getConnection());
			CurrencyRateDetailDAO l_CurrencyRateDetailDAO = CommonDAOFactory.getCurrencyRateDetailDAO(dbManager.getConnection());
			currencyRateDAO.update(currencyRate);

			Log l_logentity = new Log();
			l_logentity.setTablename("CurrencyRate");
			l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
			l_logentity.setKey(currencyRate.getCurrencyRateId());
			l_logentity.setUserid(currencyRate.getUserid());
			l_logentity.setLogstatus(Log.__UPDATE_DATA);
			logDAO.getData(l_logentity);
			
			currencyRate.getCurrencyRateDetail().setCurrencyRateId(currencyRate.getCurrencyRateId());
			currencyRate.getCurrencyRateDetail().setCurrencyRateDetailId(KeyGenerator.generateKey(dbManager.getConnection()));
			l_CurrencyRateDetailDAO.create(currencyRate.getCurrencyRateDetail());

			l_logentity.setTablename("CurrencyRateDetail");
			l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
			l_logentity.setKey(currencyRate.getCurrencyRateDetail().getCurrencyRateDetailId());
			l_logentity.setUserid(currencyRate.getUserid());
			l_logentity.setLogstatus(Log.__UPDATE_DATA);
			logDAO.getData(l_logentity);
			
			IAIMSCurrencyRateDAO l_currencyRateDAO = CommonDAOFactory.getIAIMSCurrencyRateDAO(l_DBManager.getConnection());
			IAIMSCurrencyRateDetailDAO l_detailDAO = CommonDAOFactory.getIAIMSCurrencyRateDetailDAO(l_DBManager.getConnection());
			
			CurrencyRate l_existingCR = l_currencyRateDAO.findByCode(currencyRate.getCurrencyRateCode(),currencyRate.getBranchId());
			if(l_existingCR == null){
				currencyRate.setCurrencyRateId(KeyGenerator.generateKey(l_DBManager.getConnection()));
				if(currencyRate.getRoper().equals("D"))
					currencyRate.setRoper("0");
				else if(currencyRate.getRoper().equals("M"))
					currencyRate.setRoper("1");
				l_currencyRateDAO.create(currencyRate);
				currencyRate.getCurrencyRateDetail().setCurrencyRateId(currencyRate.getCurrencyRateId());
			}else{
				currencyRate.setCurrencyRateId(l_existingCR.getCurrencyRateId());
				l_currencyRateDAO.update(currencyRate);
				currencyRate.getCurrencyRateDetail().setCurrencyRateId(l_existingCR.getCurrencyRateId());
			}
			
			currencyRate.getCurrencyRateDetail().setCurrencyRateDetailId(KeyGenerator.generateKey(l_DBManager.getConnection()));
			l_detailDAO.create(currencyRate.getCurrencyRateDetail());
			
			
			l_DBManager.commitTransaction();
			dbManager.commitTransaction();
		} catch (Exception e) {
			l_DBManager.rollBackTransaction();
			dbManager.rollBackTransaction();
			throw e;
		}finally{
			l_DBManager.closeConnection();
			dbManager.closeConnection();
		}
	}
	
	public void deleteCurrencyRate(long key,long userid)throws Exception{
		DBManager l_dbManager = DBManagerFactory.getDBManager(sessionId, DBManager.LINKED_IAIMS);
		openConnection();
		try {
			dbManager.beginTransaction();
			currencyRateDAO = CommonDAOFactory.getCurrencyRateDAO(dbManager.getConnection());
			
			IAIMSCurrencyRateDAO l_CurrencyRateDAO = CommonDAOFactory.getIAIMSCurrencyRateDAO(l_dbManager.getConnection());
			IAIMSCurrencyRateDetailDAO l_detailDOA = CommonDAOFactory.getIAIMSCurrencyRateDetailDAO(l_dbManager.getConnection());
			CurrencyRate l_localCR = currencyRateDAO.find(key);
			CurrencyRate l_existingCR = l_CurrencyRateDAO.findByCode(l_localCR.getCurrencyRateCode(), l_localCR.getBranchId());
			
			l_detailDOA.deleteByCurrencyRateId(l_existingCR.getCurrencyRateId());
			l_CurrencyRateDAO.delete(l_existingCR.getCurrencyRateId());
			
			CurrencyRateDetailDAO l_CurrencyRateDetailDAO = CommonDAOFactory.getCurrencyRateDetailDAO(dbManager.getConnection());

			logDAO = CommonDAOFactory.getLogDAO(getConnection());
			Log l_logentity = new Log();
			l_logentity.setTablename("CurrencyRate");
			l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
			l_logentity.setKey(key);
			l_logentity.setUserid(userid);
			l_logentity.setLogstatus(Log.__DELETE_DATA);
			logDAO.getData(l_logentity);
			
			ArrayList<CurrencyRateDetail> l_list = l_CurrencyRateDetailDAO.getDetailListByRateId(key);
			
			for(int i = 0; i < l_list.size(); i++) {
				l_logentity.setTablename("CurrencyRateDetail");
				l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
				l_logentity.setKey(l_list.get(i).getCurrencyRateDetailId());
				l_logentity.setUserid(userid);
				l_logentity.setLogstatus(Log.__DELETE_DATA);
				logDAO.getData(l_logentity);
			}
			
			l_CurrencyRateDetailDAO.deleteByCurrencyRateId(key);
			currencyRateDAO.delete(key);
			
			l_dbManager.commitTransaction();
			dbManager.commitTransaction();
		} catch (SQLException e) {
			l_dbManager.rollBackTransaction();
			dbManager.rollBackTransaction();
			if(e.getErrorCode() == ForeignConflictException.FOREIGN_CONFLICT_ERROR_CODE)
				throw new ForeignConflictException(e);
			else
				throw e;
		}
		finally{
			l_dbManager.closeConnection();
			dbManager.closeConnection();
		}
	}
	
	public CurrencyRate findCurrencyRate(long key)throws Exception{
		openConnection();
		try {
			currencyRateDAO = CommonDAOFactory.getCurrencyRateDAO(dbManager.getConnection());
			CurrencyRateDetailDAO l_CurrencyRateDetailDAO = CommonDAOFactory.getCurrencyRateDetailDAO(dbManager.getConnection());
			
			CurrencyRate l_CurrencyRate = currencyRateDAO.find(key);
			l_CurrencyRate.setCurrencyRateDetail(l_CurrencyRateDetailDAO.findLatest(key));
			return l_CurrencyRate;
		} catch (Exception e) {
			throw e;
		}
		finally{
			dbManager.closeConnection();
		}
	}
	
	public CurrencyRateDetail findLatestCurrencyRateDetail(long sourceCurrencyId, long convertCurrencyId,long branchId)throws Exception{
		openConnection();
		try {
			currencyRateDAO = CommonDAOFactory.getCurrencyRateDAO(dbManager.getConnection());
			CurrencyRateDetailDAO l_CurrencyRateDetailDAO = CommonDAOFactory.getCurrencyRateDetailDAO(dbManager.getConnection());
			
			CurrencyRate l_CurrencyRate = currencyRateDAO.find(sourceCurrencyId, convertCurrencyId,branchId);
			if(l_CurrencyRate != null)
			{
				CurrencyRateDetail l_rateDeail = l_CurrencyRateDetailDAO.findLatest(l_CurrencyRate.getCurrencyRateId());
				l_rateDeail.setRateOperator(l_CurrencyRate.getRoper());
				return l_rateDeail;
			}
			else
				return null;
		} catch (Exception e) {
			throw e;
		}
		finally{
			dbManager.closeConnection();
		}
	}
	
	public CurrencyRateDataList getList(CurrencyRate cri)throws Exception{
		openConnection();
		try {
			currencyRateDAO = CommonDAOFactory.getCurrencyRateDAO(dbManager.getConnection());
			return currencyRateDAO.getList(cri);
		} catch (Exception e) {
			throw e;
		}
		finally{
			dbManager.closeConnection();
		}
	}
	
	/** MBC **/
	public CurrencyRate findCurrencyRateByCode(String code) throws Exception {
		openConnection();
		try {
			currencyRateDAO = CommonDAOFactory.getCurrencyRateDAO(dbManager.getConnection());
			return currencyRateDAO.findCurrencyRateByCode(code);
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	//MBC(6/8/2014)
	public JasperPrint prepareCurrencyRateReport(CurrencyRateRpt info)
			throws Exception {
		openConnection();
		JasperPrint l_jsPrint = null;
		try {
			currencyRateDAO = CommonDAOFactory.getCurrencyRateDAO(dbManager.getConnection());
			JRResultSetDataSource l_jrRS = new JRResultSetDataSource(currencyRateDAO.prepareCurrencyRateReport(info));

			JasperReport l_jsRpt = (JasperReport) JRLoader
					.loadObjectFromFile(CommonSingleton.ABSOLUTE_PATH
							+ "reports/CurrencyRateRpt.jasper");
			HashMap<String, Object> l_params = new HashMap<String, Object>();
			l_params.put("company", "MBC");
			l_jsPrint = JasperFillManager.fillReport(l_jsRpt, l_params, l_jrRS);

		} catch (JRException je) {
			throw je;
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}

		return l_jsPrint;

	}
	
	public CurrencyRate getSourcetoHomeRate(long source_currency,long branchId) throws Exception {
		CurrencyRate l_result = new CurrencyRate();
		openConnection();
		try {
            beginTransaction();
            currencyRateDAO = CommonDAOFactory.getCurrencyRateDAO(dbManager.getConnection());
			Currency l_infocurency=new Currency();
			if(l_infocurency != null){
				CurrencyRate l_infocurrencyrate=new CurrencyRate();
				l_infocurrencyrate.setSourceCurrencyId(source_currency);
				l_infocurrencyrate.setBranchId(branchId);
				l_infocurrencyrate = currencyRateDAO.getCurrencyRateFromSourcetoHome(l_infocurrencyrate.getSourceCurrencyId(),l_infocurrencyrate.getBranchId());
				l_result = l_infocurrencyrate ;
			}
			commintTransaction();
		} catch (Exception e) {
			throw e;
		}
		finally
		{
			closeConnection();
		}
		return l_result;
	}
	
	public CurrencyRate find(long sourceCurrencyId, long convertCurrencyId,long branchId)throws Exception{
		CurrencyRate l_result = new CurrencyRate();
		openConnection();
		try {
            beginTransaction();
            currencyRateDAO = CommonDAOFactory.getCurrencyRateDAO(dbManager.getConnection());
			Currency l_infocurency=new Currency();
			if(l_infocurency != null){
				CurrencyRate l_infocurrencyrate=new CurrencyRate();
				l_infocurrencyrate.setSourceCurrencyId(sourceCurrencyId);
				l_infocurrencyrate.setConvertCurrencyId(convertCurrencyId);
				l_infocurrencyrate.setBranchId(branchId);
				l_infocurrencyrate = currencyRateDAO.find(l_infocurrencyrate.getSourceCurrencyId(),l_infocurrencyrate.getConvertCurrencyId(),l_infocurrencyrate.getBranchId());
				l_result = l_infocurrencyrate ;
			}
			commintTransaction();
		} catch (Exception e) {
			throw e;
		}
		finally
		{
			closeConnection();
		}
		return l_result;
	}
	//MBC End
	
/*	public static long getIAIMSCurrencyRateId(long localCurrencyRateId, Connection localConnection, Connection linkedConnection)throws Exception{
		CurrencyRate l_localCurrencyRate = CommonDAOFactory.getCurrencyRateDAO(localConnection).find(localCurrencyRateId);
		
		IAIMSCurrencyRateDAO l_iaimsCurrencyRateDAO = CommonDAOFactory.getIAIMSCurrencyRateDAO(linkedConnection);
		CurrencyRate l_currencyRate = l_iaimsCurrencyRateDAO.findByCode(l_localCurrencyRate.getCurrencyRateCode(), l_localCurrencyRate.getBranchId());
		if(l_currencyRate == null){
			l_currencyRate = l_localCurrencyRate;
			l_currencyRate.setCurrencyRateId(KeyGenerator.generateKey(linkedConnection));
			l_iaimsCurrencyRateDAO.create(l_currencyRate);
		}
		return l_currencyRate.getCurrencyRateId();
	}*/
}
